/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Wang Yizhuo (wangyizhuo@gmail.com) - patch (see Bugzilla #239178) 
 *******************************************************************************/
package org.eclipse.ui.internal.forms.widgets;

//import java.util.Arrays;
import java.util.HashMap;

import org.eclipse.jface.resource.ImageDescriptor;
//import org.eclipse.jface.resource.JFaceResources;
//import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.swt.graphics.Color;
//import org.eclipse.swt.graphics.Device;
//import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
//import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.RGB;

public class FormImages {
	private static FormImages instance;

	public static FormImages getInstance() {
		if (instance == null)
			instance = new FormImages();
		return instance;
	}

//	private LocalResourceManager resources;
	private HashMap descriptors;
	
	private FormImages() {
	}
	
	private abstract class AbstractImageDescriptor extends ImageDescriptor {
		RGB[] fRGBs;
		int fLength;
		
		AbstractImageDescriptor(Color[] colors, int length) {
			fRGBs = new RGB[colors.length];
			for (int i = 0; i < colors.length; i++) {
				Color color = colors[i];
				fRGBs[i] = color == null ? null : color.getRGB();
			}
			fLength = length;
		}
		
		public boolean equals(Object obj) {
			if (obj instanceof AbstractImageDescriptor) {
				AbstractImageDescriptor id = (AbstractImageDescriptor)obj;
				if (id.fRGBs.length == fRGBs.length) {
					boolean result = id.fLength == fLength;
					for (int i = 0; i < fRGBs.length && result; i++) {
						result = result && id.fRGBs[i].equals(fRGBs[i]);
					}
					return result;
				}
			}
			return false;
		}
		
		public int hashCode() {
			int hash = 0;
			for (int i = 0; i < fRGBs.length; i++)
				hash = hash * 7 + fRGBs[i].hashCode();
			hash = hash * 7 + fLength;
			return hash;
		}
	}

// RAP [if] Unused code: was used by getGradient    
//	private class SimpleImageDescriptor extends AbstractImageDescriptor{
//		private int fTheight;
//		private int fMarginHeight;
//		
//		SimpleImageDescriptor (Color color1, Color color2,
//				int realtheight, int theight, int marginHeight) {
//			super(new Color[] {color1, color2}, realtheight);
//			fTheight = theight;
//			fMarginHeight = marginHeight;
//		}
//		
//		public boolean equals(Object obj) {
//			if (obj instanceof SimpleImageDescriptor) {
//				SimpleImageDescriptor id = (SimpleImageDescriptor) obj;
//				if (super.equals(obj)  &&
//						id.fTheight == fTheight && id.fMarginHeight == fMarginHeight)
//					return true;
//			}
//			return false;
//		}
//		
//		public int hashCode() {
//			int hash = super.hashCode();
//			hash = hash * 7 + new Integer(fTheight).hashCode();
//			hash = hash * 7 + new Integer(fMarginHeight).hashCode();
//			return hash;
//		}
//
//		public ImageData getImageData() {
//			return null;
//		}
//		
//		public Image createImage(boolean returnMissingImageOnError,	Device device) {
//			Image image = new Image(device, 1, fLength);
//			Color color1 = new Color(device, fRGBs[0]);
//			Color color2 = new Color(device, fRGBs[1]);
//			image.setBackground(color1);
//			GC gc = new GC(image);
//			gc.setBackground(color1);
//			gc.fillRectangle(0, 0, 1, fLength);
//			gc.setForeground(color2);
//			gc.setBackground(color1);
//			gc.fillGradientRectangle(0, fMarginHeight + 2, 1, fTheight - 2, true);
//			gc.dispose();
//			color1.dispose();
//			color2.dispose();
//			return image;
//		}
//	}
	
//	private class ComplexImageDescriptor extends AbstractImageDescriptor {
//		RGB fBgRGB;
//		boolean fVertical;
//		int[] fPercents;
//		
//		public ComplexImageDescriptor(Color[] colors, int length,
//				int[] percents, boolean vertical, Color bg) {
//			super(colors, length);
//			fBgRGB = bg == null ? null : bg.getRGB();
//			fVertical = vertical;
//			fPercents = percents;
//		}
//		
//		public boolean equals(Object obj) {
//			if (obj instanceof ComplexImageDescriptor) {
//				ComplexImageDescriptor id = (ComplexImageDescriptor) obj;
//				if (super.equals(obj)  &&
//						id.fVertical == fVertical && Arrays.equals(id.fPercents, fPercents)) {
//					if ((id.fBgRGB == null && fBgRGB == null) ||
//							(id.fBgRGB != null && id.fBgRGB.equals(fBgRGB)))
//						return true;
//					// if the only thing that isn't the same is the background color
//					// still return true if it does not matter (percents add up to 100)
//					int sum = 0;
//					for (int i = 0; i < fPercents.length; i++)
//						sum += fPercents[i];
//					if (sum >= 100)
//						return true;
//				}
//			}
//			return false;
//		}
//		
//		public int hashCode() {
//			int hash = super.hashCode();
//			hash = hash * 7 + new Boolean(fVertical).hashCode();
//			for (int i = 0; i < fPercents.length; i++)
//				hash = hash * 7 + new Integer(fPercents[i]).hashCode();
//			return hash;
//		}
//
//		public ImageData getImageData() {
//			return null;
//		}
//		
//		public Image createImage(boolean returnMissingImageOnError,	Device device) {
//			int width = fVertical ? 1 : fLength;
//			int height = fVertical ? fLength : 1;
//			Image gradient = new Image(device, Math.max(width, 1), Math
//					.max(height, 1));
//			GC gc = new GC(gradient);
//			Color[] colors = new Color[fRGBs.length];
//			for (int i = 0; i < colors.length; i++)
//				colors[i] = new Color(device, fRGBs[i]);
//			Color bg = fBgRGB == null ? null : new Color(device, fBgRGB);
//			drawTextGradient(gc, width, height, colors, fPercents, fVertical, bg);
//			gc.dispose();
//			for (int i = 0; i < colors.length; i++)
//				colors[i].dispose();
//			if (bg != null)
//				bg.dispose();
//			return gradient;
//		}
//
//		private void drawTextGradient(GC gc, int width, int height, Color[] colors,
//				int[] percents, boolean vertical, Color bg) {
//			final Color oldBackground = gc.getBackground();
//			if (colors.length == 1) {
//				if (colors[0] != null)
//					gc.setBackground(colors[0]);
//				gc.fillRectangle(0, 0, width, height);
//			} else {
//				final Color oldForeground = gc.getForeground();
//				Color lastColor = colors[0];
//				if (lastColor == null)
//					lastColor = oldBackground;
//				int pos = 0;
//				for (int i = 0; i < percents.length; ++i) {
//					gc.setForeground(lastColor);
//					lastColor = colors[i + 1];
//					if (lastColor == null)
//						lastColor = oldBackground;
//					gc.setBackground(lastColor);
//					if (vertical) {
//						int gradientHeight = percents[i] * height / 100;
//						
//						gc.fillGradientRectangle(0, pos, width, gradientHeight,
//								true);
//						pos += gradientHeight;
//					} else {
//						int gradientWidth = percents[i] * width / 100;
//						
//						gc.fillGradientRectangle(pos, 0, gradientWidth, height,
//								false);
//						pos += gradientWidth;
//					}
//				}
//				if (vertical && pos < height) {
//					if (bg != null)
//						gc.setBackground(bg);
//					gc.fillRectangle(0, pos, width, height - pos);
//				}
//				if (!vertical && pos < width) {
//					if (bg != null)
//						gc.setBackground(bg);
//					gc.fillRectangle(pos, 0, width - pos, height);
//				}
//				gc.setForeground(oldForeground);
//			}
//		}
//	}
	
//	public Image getGradient(Color color1, Color color2,
//			int realtheight, int theight, int marginHeight) {
//		if (color1 == null || color1.isDisposed() || color2 == null || color2.isDisposed())
//			return null;
//		AbstractImageDescriptor desc = new SimpleImageDescriptor(color1, color2, realtheight, theight, marginHeight);
//		return getGradient(desc);
//	}
	
//	public Image getGradient(Color[] colors, int[] percents,
//			int length, boolean vertical, Color bg) {
//		if (colors.length == 0)
//			return null;
//		for (int i = 0; i < colors.length; i++)
//			if (colors[i] == null || colors[i].isDisposed())
//				return null;
//		if (bg != null && bg.isDisposed())
//			return null;
//		AbstractImageDescriptor desc = new ComplexImageDescriptor(colors, length, percents, vertical, bg);
//		return getGradient(desc);
//	}
	
//	private synchronized Image getGradient(AbstractImageDescriptor desc) {
//		checkHashMaps();
//		Image result = getResourceManager().createImage(desc);
//		descriptors.put(result, desc);
//		return result;
//	}
	
	public synchronized boolean markFinished(Image image) {
		checkHashMaps();
		AbstractImageDescriptor desc = (AbstractImageDescriptor)descriptors.get(image);
		if (desc != null) {
// RAP [if] unnecessary to destroy image
//			getResourceManager().destroyImage(desc);
//			if (getResourceManager().find(desc) == null) {
				descriptors.remove(image);
				validateHashMaps();
//			}
			return true;
		}
		// if the image was not found, dispose of it for the caller
// RAP [if] unnecessary
//		image.dispose();
		return false;
	}

// RAP [if] unused	
//	private LocalResourceManager getResourceManager() {
//		if (resources == null)
//			resources = new LocalResourceManager(JFaceResources.getResources());
//		return resources;
//	}

	private void checkHashMaps() {
		if (descriptors == null)
			descriptors = new HashMap();
	}
	
	private void validateHashMaps() {
		if (descriptors.size() == 0)
			descriptors = null;
	}
}
